﻿/*******************************************************************
Copyright (c) 2011 이재범

*  Permission is hereby granted, free of charge, to any person
*  obtaining a copy of this software and associated documentation
*  files (the "Software"), to deal in the Software without
*  restriction, including without limitation the rights to use,
*  copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the
*  Software is furnished to do so, subject to the following
*  conditions:
* 
*  The above copyright notice and this permission notice shall be
*  included in all copies or substantial portions of the Software.
* 
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
*  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
*  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
*  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
*  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
*  OTHER DEALINGS IN THE SOFTWARE.
*******************************************************************/

#include "equation.h"
#include "exception.h"

#include <algorithm>
#include <iostream>
#include <map>
#include <vector>

#pragma once

string process_hash_value(string original_equation);
string generate_hash_code(string equation);
string get_operand_address_table(string equation, double& det);
void operand_table_rank(map<string, vector<string>> &operand_address_table, map<string, int>& operand_rank);
vector<string> what_operator_braket(string &equation, int location);
double create_relation_matrix(string equation, double& det);

class Hash : public Equation
{
private:
	string hash_data;
	bool is_valid_hash;

public:

	Hash() {}
	Hash(string x) : Equation(x){}
	void save_hash_data(string _store_location)
	{
		data = hash_data;
		save_data(_store_location);
	}
	void append_hash_data(string _store_location)
	{
		data = hash_data + "\n";
		append_data(_store_location);
	}

	string get_hash()
	{
		return hash_data;
	}
	
	// hash 에서 전체식의 hash, 그리고 가장 큰 부분식, 연산자, 그리고 그 부분식들의 det 값들을 추출한다. 
	void extract_searching_query(string &entire_hash, vector<string> &hash_operand, 
		vector<string> &hash_operator, vector<string> &hash_det);

	void generate_hash_data(); // 전체 해시 데이터를 생성한다.
	void print_hash_data()
	{
		string::iterator itr = hash_data.begin();
		while (itr != hash_data.end())
		{
			cout << (int)((unsigned char)(*itr)) << " ";
			itr ++;
		}
		cout << endl;
		cout << "total length : " << hash_data.length() << " bytes! " << endl;
	}
};